<?php

namespace tch\core;

use tch\core\RouterInterface;
use tch\core\Request;

/**
 * 控制器父类
 * @package tch.core
 */
abstract class Controller
{

    /**
     *
     * @var RouterInterface
     */
    protected $router;

    /**
     * 视图要用的变量全部存到这里
     * @var array 
     */
    protected $vars = array();

    /**
     * 构造函数
     * @param RouterInterface $router 路由解析类示例
     */
    public function __construct(RouterInterface $router)
    {
        $this->router = $router;
        
        $this->initialize();
    }
    
    /**
     * 
     * 子类初始化
     */
    protected function initialize()
    {
        return;
    }

    /**
     * 对 \tch\core\Router::url() 方法进行封装
     * @param string $route
     * @param array $params
     * @param string $host
     * @return string
     */
    protected function url($route, $params = array(), $host = '')
    {
        return $this->router->url($route, $params, $host);
    }

    /**
     * 获取当前控制器标识名称
     * @return string
     */
    protected function getControl()
    {
        return $this->router->getControl();
    }

    /**
     * 获取当前动作标识名称
     * @return string
     */
    protected function getAction()
    {
        return $this->router->getAction();
    }

    /**
     * 完整的route标识,用于在视图中做状态判断
     * @return string 如 'class/create'
     */
    protected function getRoute()
    {
        return $this->router->getControl() . '/' . $this->router->getAction();
    }

    /**
     * 设置视图中要用的各种变量
     * @param string $k 变量名
     * @param string $v 变量值
     * @return void 
     */
    public function setVar($k, $v)
    {
        $this->vars[$k] = $v;
    }

    /**
     * 引入模版显示
     * @param string $tpl 模板文件名 不含后缀
     */
    protected function display($tpl = '')
    {
        global $_G;

        extract($this->vars);

        include template($this->getTplFile($tpl));
    }
    
    /**
     * 显示提示消息 对于 showmessage 函数的包裹,更 OO-Style
     * @param string $message
     * @param string $url_forward
     * @param array $values
     * @param array $extra_param 
     * <pre>
     *      [
     *          'break' => bool, //是否执行完hook就终止,默认false 
     *          'showdialog'=>, //移动端无效
     *          'closetime'=>, //移动端无效
     *          'extrajs'=>, //移动端无效
     *          'clean_msgforward'=>,
     *          'set'=>,
     *          'refreshtime'=>, 
     *          'timeout'=>, 
     *          'login' => bool, //是否显示登录框 默认false
     *          'header'=> bool, //是否301重定向 默认false
     *          'location' => bool, //是否在ajax请求返回时进行页面跳转,默认false
     *          'alert' => , 
     *          'msgtype' => int, //  1-|2-|3- 默认1
     *          'showmsg' => bool, //是否显示消息文本 默认true
     *          'showid' => , 
     *          'return' => , 
     *          'handle' => , 
     *          'locationtime' => 
     *      ]
     * </pre>
     * @param false $custom 是否自定义消息格式 默认否
     */
    protected function message($message, $url_forward = '', $values = array(), $extra_param = array(), $custom = false)
    {
        showmessage($message, $url_forward, $values, $extra_param, $custom);
    }
    
    /**
     * 页面跳转 对 dheader 函数的包裹,更 OO-Style
     * @param string $url
     * @param bool $replace
     * @param int $http_response_code
     */
    protected function jump($url, $replace = true, $http_response_code = 0)
    {
        dheader('location: ' . $url, $replace, $http_response_code);
    }

    /**
     * 构造当前模块下指定模版文件名
     * @param string $tpl_name
     * @return string
     */
    protected function getTplFile($tpl_name = '')
    {
        return TCH_APP_ID . ':' . $this->getControl() . '_' . ($tpl_name ? $tpl_name : $this->getAction());
    }
    
    /**
     * 获取输入参数 支持过滤和默认值;基于TP的I方法,放弃了Discuz自带的getgpc()函数
     * 使用方法:
     * <code>
     * $this->input('id',0); 获取id参数 自动判断get或者post
     * $this->input('post.name','','htmlspecialchars'); 获取$_POST['name']
     * $this->input('get.'); 获取$_GET
     * </code>
     * @param string $name 变量的名称 支持指定类型
     * @param mixed $default 不存在的时候默认值
     * @param mixed $filter 参数过滤方法
     * @param mixed $datas 要获取的额外数据源
     * @return mixed
     */
    protected function input($name, $default = '', $filter = null, $datas = null)
    {
        return Request::input($name, $default, $filter, $datas);
    }

}
